'use strict';

const path = require('path');
const fsExtra = require('fs-extra');
const pkgDir = require('pkg-dir').sync;
const npminstall = require('npminstall');
const { isObject } = require('@caiheping-cli-dev/utils');
const formatPath = require('@caiheping-cli-dev/format-path');
const { getDefaultRegistry, getNpmLatestVersion } = require('@caiheping-cli-dev/get-npm-info');
const pathExists = require('path-exists').sync;

class Package {
    constructor(options) {
        if (!options) {
            throw new Error('Package 类的options参数不能为空！');
        }
        if (!isObject(options)) {
            throw new Error('Package 类的options参数必须为对象！');
        }
        this.targetPath = options.targetPath;
        this.storeDir = options.storeDir;
        this.packageName = options.packageName;
        this.packageVersion = options.packageVersion;
        // package缓存目录前缀
        this.cacheFilePathPrefix = this.packageName.replace('/', '_')
    }

    get cacheFilePath() {
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`)
    }

    getSpecificCacheFilePath(packageVersion) {
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${packageVersion}@${this.packageName}`)
    }

    async prepare() {
        // 目录不存在，创建目录
        if (this.storeDir && !pathExists(this.storeDir)) {
            fsExtra.mkdirpSync(this.storeDir);
        }
        // 把最新版本转换为具体版本号
        if (this.packageVersion === 'latest') {
            this.packageVersion = await getNpmLatestVersion(this.packageName);
        }
    }

    // 判断是否存在
    async exists() {
        if (this.storeDir) {
            await this.prepare();
            return pathExists(this.cacheFilePath);
        } else {
            return pathExists(this.targetPath);
        }
    }

    // 安装package
    async install() {
        await this.prepare();
        // npminstall()时异步的
        return npminstall({
            root: this.targetPath,
            storeDir: this.stroeDir,
            registry: getDefaultRegistry(),
            pkgs: [
                {
                    name: this.packageName,
                    version: this.packageVersion
                }
            ]
        })
    }

    // 更新package
    async update() {
        await this.prepare();
        // 获取最新版本号
        const latestPackageVersion = await getNpmLatestVersion(this.packageName);
        // 查询最新版本号路径是否存在
        const latestFilePath = this.getSpecificCacheFilePath(latestPackageVersion);
        // 如果不存在，安装最新版本
        if (!pathExists(latestFilePath)) {
            await npminstall({
                root: this.targetPath,
                storeDir: this.stroeDir,
                registry: getDefaultRegistry(),
                pkgs: [
                    {
                        name: this.packageName,
                        version: latestPackageVersion
                    }
                ]
            })
        }
        this.packageVersion = latestPackageVersion;
    }

    // 获取入口文件的路径
    getRootFilePath() {
        function _getRootFile(targetPath) {
            // 获取package.json 所在目录
            const dir = pkgDir(targetPath);
            if(dir){
                // 读取package.json
                const pkgFile = require(path.resolve(dir, 'package.json'));
                // 查找package的入口文件路径（main属性下面）
                if(pkgFile && pkgFile.main) {
                    // 路径的兼容（window/mac)
                    // console.log(path.resolve(dir, pkgFile.main))
                    return formatPath(path.resolve(dir, pkgFile.main));
                }
            }
        }
        if (this.storeDir) {
            return _getRootFile(this.cacheFilePath);
        } else {
            return _getRootFile(this.targetPath);
        }
    }
}

module.exports = Package;

